'''
Description: 
Author: notplus
Date: 2021-12-13 18:51:17
LastEditors: notplus
LastEditTime: 2021-12-14 18:56:32
FilePath: /two_stage_cluster.py

Copyright (c) 2021 notplus
'''

from math import pi
import pickle
import numpy as np
from numpy.core.fromnumeric import sort
from pyproj import Transformer
import matplotlib.pyplot as plt
from sklearn import cluster
from sklearn.cluster import DBSCAN

import utils
from extra_stay_points import User, Trajectory, StayPoint, ActivityCluster
from dbscan import DBSCAN
import sklearn.cluster

# pickle_filename = 'activity.pickle'
pickle_filename = 'activity_153.pickle'

with open(pickle_filename, 'rb') as f:
    users = pickle.load(f)

all_activity = []
for user in users:
    all_activity += (user.trajs.stay_points)

all_activity.sort(key=lambda act: act.lev_t - act.arv_t)

time_interval = []

for user in users:
    i = 0
    point_num = len(user.trajs.stay_points)
    distance_matrix = np.zeros((point_num, point_num))
    time_interval_matrix = np.zeros((point_num, point_num))

    for i in range(point_num):
        for j in range(i + 1, point_num):
            distance_matrix[j][i] = distance_matrix[i][j] = utils.compute_dist(user.trajs.stay_points[i], user.trajs.stay_points[j])
    
    db = cluster.DBSCAN(eps=5, metric='precomputed',
                min_samples=1, n_jobs=-1).fit(distance_matrix)
    labels = db.labels_

    n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
    print('num cluster: %d' % (n_clusters_))

    for i in range(len(user.trajs.stay_points)-1):
        # if (user.trajs.stay_points[i+1].arv_t - user.trajs.stay_points[i].lev_t).total_seconds() == 0:
        #     print('000')
        time_interval.append(
            (user.trajs.stay_points[i+1].arv_t - user.trajs.stay_points[i].lev_t).total_seconds())

    for i in range(point_num):
        for j in range(i + 1, point_num):
            distance_matrix[j][i] = distance_matrix[i][j] = utils.compute_dist(user.trajs.stay_points[i], user.trajs.stay_points[j])

    for i in range(point_num):
        for j in range(i + 1, point_num):
            arv_t = (user.trajs.stay_points[j].arv_t - user.trajs.stay_points[j].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600
            lev_t = (user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600
            
            time_interval_matrix[j][i] = time_interval_matrix[i][j] = abs(lev_t - arv_t)

    # np.save('time_interval_matrix_128.npy', time_interval_matrix)
    # np.save('distance_matrix_128.npy', distance_matrix)

    # distance_matrix = np.load('distance_matrix_153.npy')
    # time_interval_matrix = np.load('time_interval_matrix_153.npy')

    print(np.mean(time_interval) / 3600)

    c = DBSCAN(user.trajs.stay_points, np.mean(time_interval) / 3600, 15, 1)

    all_activity_cluster = []
    for key in c:
        activities = []
        for act in c[key]:
            activities.append(user.trajs.stay_points[act])
        all_activity_cluster.append(ActivityCluster(activities))

    # with open('all_activity_cluster_153.pickle', 'wb') as f:
    #     pickle.dump(all_activity_cluster, f)

    # with open('cluster_153.pickle', 'wb') as f:
    #     pickle.dump(c, f)
    
    # with open('cluster_153.pickle', 'rb') as f:
    #     c = pickle.load(f)

    # db = DBSCAN(eps=15, metric='precomputed', min_samples=1).fit(distance_matrix)
    # labels = db.labels_
    # n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

    # # plt.figure()
    # # plt.hist(labels, bins=n_clusters_)

    # print('num cluster: %d' % (n_clusters_))
    label_sort = sorted(c, key=lambda key : len(c[key]))[::-1]
    
    # max_label = max(c, key=lambda key : len(c[key]))


    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    for j in range(5):
        x = []
        y = []
        z = []
        
        for i in c[label_sort[j]]:
            transformer = Transformer.from_crs("epsg:4326", "epsg:32650") 
            xt, yt = transformer.transform(user.trajs.stay_points[i].lat, user.trajs.stay_points[i].lng)
            x.append(xt)
            y.append(yt)
            z.append((user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600)
    
        ax.scatter(x, y, z, marker='o')

    for j in range(5):
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        x = []
        y = []
        z = []
        
        for i in c[label_sort[j]]:
            transformer = Transformer.from_crs("epsg:4326", "epsg:32650") 
            xt, yt = transformer.transform(user.trajs.stay_points[i].lat, user.trajs.stay_points[i].lng)
            x.append(xt)
            y.append(yt)
            z.append((user.trajs.stay_points[i].arv_t - user.trajs.stay_points[i].arv_t.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() / 3600)
    
        ax.scatter(x, y, z, marker='o')


    print('')

    